{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "import tensorflow as tf\n",
    "from tensorflow import keras"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 加载数据 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "(train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.mnist.load_data()\n",
    "\n",
    "train_labels = train_labels[:1000]\n",
    "test_labels = test_labels[:1000]\n",
    "\n",
    "train_images = train_images[:1000].reshape(-1, 28 * 28) / 255.0\n",
    "test_images = test_images[:1000].reshape(-1, 28 * 28) / 255.0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 定义模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "dense (Dense)                (None, 512)               401920    \n",
      "_________________________________________________________________\n",
      "dropout (Dropout)            (None, 512)               0         \n",
      "_________________________________________________________________\n",
      "dense_1 (Dense)              (None, 10)                5130      \n",
      "=================================================================\n",
      "Total params: 407,050\n",
      "Trainable params: 407,050\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "def create_model():\n",
    "  model = tf.keras.models.Sequential([\n",
    "    keras.layers.Dense(512, activation='relu', input_shape=(784,)),\n",
    "    keras.layers.Dropout(0.2),\n",
    "    keras.layers.Dense(10)\n",
    "  ])\n",
    "\n",
    "  model.compile(optimizer='adam',\n",
    "                loss=tf.losses.SparseCategoricalCrossentropy(from_logits=True),\n",
    "                metrics=['accuracy'])\n",
    "\n",
    "  return model\n",
    "\n",
    "model = create_model()\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 保存数据 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 1000 samples, validate on 1000 samples\n",
      "Epoch 1/10\n",
      " 736/1000 [=====================>........] - ETA: 0s - loss: 1.3803 - accuracy: 0.6060\n",
      "Epoch 00001: saving model to training_1/cp.ckpt\n",
      "1000/1000 [==============================] - 1s 964us/sample - loss: 1.1760 - accuracy: 0.6610 - val_loss: 0.7519 - val_accuracy: 0.7660\n",
      "Epoch 2/10\n",
      " 768/1000 [======================>.......] - ETA: 0s - loss: 0.4352 - accuracy: 0.8659\n",
      "Epoch 00002: saving model to training_1/cp.ckpt\n",
      "1000/1000 [==============================] - 0s 377us/sample - loss: 0.4231 - accuracy: 0.8710 - val_loss: 0.5208 - val_accuracy: 0.8320\n",
      "Epoch 3/10\n",
      " 704/1000 [====================>.........] - ETA: 0s - loss: 0.3011 - accuracy: 0.9233\n",
      "Epoch 00003: saving model to training_1/cp.ckpt\n",
      "1000/1000 [==============================] - 0s 386us/sample - loss: 0.2952 - accuracy: 0.9240 - val_loss: 0.4701 - val_accuracy: 0.8520\n",
      "Epoch 4/10\n",
      " 896/1000 [=========================>....] - ETA: 0s - loss: 0.2066 - accuracy: 0.9554\n",
      "Epoch 00004: saving model to training_1/cp.ckpt\n",
      "1000/1000 [==============================] - 0s 431us/sample - loss: 0.2074 - accuracy: 0.9540 - val_loss: 0.4639 - val_accuracy: 0.8530\n",
      "Epoch 5/10\n",
      " 736/1000 [=====================>........] - ETA: 0s - loss: 0.1480 - accuracy: 0.9715\n",
      "Epoch 00005: saving model to training_1/cp.ckpt\n",
      "1000/1000 [==============================] - 0s 363us/sample - loss: 0.1597 - accuracy: 0.9670 - val_loss: 0.4588 - val_accuracy: 0.8530\n",
      "Epoch 6/10\n",
      " 736/1000 [=====================>........] - ETA: 0s - loss: 0.1258 - accuracy: 0.9742\n",
      "Epoch 00006: saving model to training_1/cp.ckpt\n",
      "1000/1000 [==============================] - 0s 443us/sample - loss: 0.1205 - accuracy: 0.9750 - val_loss: 0.4427 - val_accuracy: 0.8520\n",
      "Epoch 7/10\n",
      " 768/1000 [======================>.......] - ETA: 0s - loss: 0.0877 - accuracy: 0.9883\n",
      "Epoch 00007: saving model to training_1/cp.ckpt\n",
      "1000/1000 [==============================] - 0s 353us/sample - loss: 0.0847 - accuracy: 0.9900 - val_loss: 0.4325 - val_accuracy: 0.8640\n",
      "Epoch 8/10\n",
      " 736/1000 [=====================>........] - ETA: 0s - loss: 0.0735 - accuracy: 0.9864\n",
      "Epoch 00008: saving model to training_1/cp.ckpt\n",
      "1000/1000 [==============================] - 0s 389us/sample - loss: 0.0691 - accuracy: 0.9900 - val_loss: 0.4441 - val_accuracy: 0.8620\n",
      "Epoch 9/10\n",
      " 736/1000 [=====================>........] - ETA: 0s - loss: 0.0539 - accuracy: 0.9946\n",
      "Epoch 00009: saving model to training_1/cp.ckpt\n",
      "1000/1000 [==============================] - 0s 453us/sample - loss: 0.0530 - accuracy: 0.9960 - val_loss: 0.4188 - val_accuracy: 0.8620\n",
      "Epoch 10/10\n",
      " 896/1000 [=========================>....] - ETA: 0s - loss: 0.0378 - accuracy: 0.9978\n",
      "Epoch 00010: saving model to training_1/cp.ckpt\n",
      "1000/1000 [==============================] - 0s 408us/sample - loss: 0.0382 - accuracy: 0.9980 - val_loss: 0.4178 - val_accuracy: 0.8640\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<tensorflow.python.keras.callbacks.History at 0x154f8861588>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "checkpoint_path = \"training_1/cp.ckpt\"\n",
    "checkpoint_dir = os.path.dirname(checkpoint_path)\n",
    "\n",
    "# 在训练中保存权重 \n",
    "cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_path,\n",
    "                                                 save_weights_only=True,\n",
    "                                                 verbose=1)  # period=5:  每五次保存一次唯一名字的检查点\n",
    "model.fit(train_images, \n",
    "          train_labels,  \n",
    "          epochs=10,\n",
    "          validation_data=(test_images,test_labels),\n",
    "          callbacks=[cp_callback])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 加载数据 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1000/1000 - 0s - loss: 0.4178 - accuracy: 0.8640\n",
      "Restored model, accuracy: 86.40%\n"
     ]
    }
   ],
   "source": [
    "latest = tf.train.latest_checkpoint(checkpoint_dir)\n",
    "model = create_model()\n",
    "model.load_weights(latest)\n",
    "loss, acc = model.evaluate(test_images,  test_labels, verbose=2)\n",
    "print(\"Restored model, accuracy: {:5.2f}%\".format(100*acc))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 保存模型 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 1000 samples\n",
      "Epoch 1/5\n",
      "1000/1000 [==============================] - 0s 344us/sample - loss: 1.1552 - accuracy: 0.6840\n",
      "Epoch 2/5\n",
      "1000/1000 [==============================] - 0s 152us/sample - loss: 0.4152 - accuracy: 0.8830\n",
      "Epoch 3/5\n",
      "1000/1000 [==============================] - 0s 136us/sample - loss: 0.2785 - accuracy: 0.9280\n",
      "Epoch 4/5\n",
      "1000/1000 [==============================] - 0s 135us/sample - loss: 0.2035 - accuracy: 0.9490\n",
      "Epoch 5/5\n",
      "1000/1000 [==============================] - 0s 137us/sample - loss: 0.1467 - accuracy: 0.9610\n",
      "INFO:tensorflow:Assets written to: saved_model\\my_model\\assets\n"
     ]
    }
   ],
   "source": [
    "model = create_model()\n",
    "model.fit(train_images, train_labels, epochs = 5)\n",
    "# 默认保存的格式为SavedModel \n",
    "model.save('saved_model\\my_model')\n",
    "# 如果要保存为HDF5格式，需要指定后缀名\n",
    "model.save('saved_model\\my_model.h5')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 加载模型 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential_5\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "dense_10 (Dense)             (None, 512)               401920    \n",
      "_________________________________________________________________\n",
      "dropout_5 (Dropout)          (None, 512)               0         \n",
      "_________________________________________________________________\n",
      "dense_11 (Dense)             (None, 10)                5130      \n",
      "=================================================================\n",
      "Total params: 407,050\n",
      "Trainable params: 407,050\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n",
      "1000/1000 - 0s - loss: 0.4300 - accuracy: 0.8620\n",
      "Restored model, accuracy: 86.20%\n",
      "(1000, 10)\n"
     ]
    }
   ],
   "source": [
    "new_model = tf.keras.models.load_model('saved_model\\my_model')\n",
    "new_model.summary()\n",
    "loss, acc = new_model.evaluate(test_images,  test_labels, verbose=2)\n",
    "print('Restored model, accuracy: {:5.2f}%'.format(100*acc))\n",
    "\n",
    "print(new_model.predict(test_images).shape)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6rc1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
